CSS Motion Pathμ κ°λ ₯ν κΈ°λ₯μΌλ‘ μ κ΅νκ³ μκ°μ μΌλ‘ λ©μ§ μ λλ©μ΄μ μ λ§λ€μ΄ 보μΈμ. μ¬μ©μ μ§μ κ²½λ‘ μ μ, μμ μμ§μ μ μ΄, μ¬μ©μ κ²½ν ν₯μ λ°©λ²μ λ°°μλλ€.
CSS Motion Path: 볡μ‘ν μ λλ©μ΄μ κΆ€μ μ μ€ν
λμμμ΄ λ°μ νλ μΉ κ°λ° νκ²½μμ, λ§€λ ₯μ μ΄κ³ λμ μΈ μ¬μ©μ κ²½νμ λ§λλ κ²μ 무μλ³΄λ€ μ€μν©λλ€. CSS Motion Pathλ κ°λ°μκ° μ¬μ©μ μ§μ κ²½λ‘λ₯Ό λ°λΌ HTML μμλ₯Ό μ΄λμν¬ μ μκ² ν΄μ£Όλ κ°λ ₯ν λκ΅¬λ‘ λ±μ₯νμΌλ©°, λ¨μν μ ν μ νμ λμ΄μ μλ‘μ΄ μ°¨μμ μ λλ©μ΄μ κ°λ₯μ±μ μ΄μ΄μ€λλ€. μ΄ μ’ ν© κ°μ΄λμμλ CSS Motion Pathμ 볡μ‘ν λ΄μ©λ€μ κΉμ΄ νκ³ λ€μ΄, κ·Έ κΈ°λ₯κ³Ό ꡬν κΈ°μ , κ·Έλ¦¬κ³ λ§€νΉμ μΈ μΉ μ λλ©μ΄μ μ μμ μν λͺ¨λ² μ¬λ‘λ₯Ό νꡬν©λλ€.
CSS Motion Pathλ 무μμΈκ°?
CSS Motion Pathλ κ°λ°μκ° λ―Έλ¦¬ μ μλ λͺ¨μ, SVG κ²½λ‘ λλ CSS μμ±μ μ¬μ©νμ¬ μ μλ μ¬μ©μ μ§μ κ²½λ‘ λ± μ§μ λ κ²½λ‘λ₯Ό λ°λΌ HTML μμλ₯Ό μ λλ©μ΄μ νν μ μλλ‘ μ§μν©λλ€. μ΄λ₯Ό ν΅ν΄ λΉμ ν κΆ€μ μ λ°λ₯΄λ 볡μ‘νκ³ μκ°μ μΌλ‘ λ§€λ ₯μ μΈ μ λλ©μ΄μ μ λ§λ€μ΄ μ¬μ©μ μνΈμμ©μ ν₯μμν€κ³ λ λͺ°μ κ° μλ κ²½νμ μ 곡ν μ μμ΅λλ€.
keyframes
λ‘ μ μλ μν κ°μ μ νμ μμ‘΄νλ κΈ°μ‘΄ CSS μ λλ©μ΄μ
κ³Ό λ¬λ¦¬, Motion Pathλ κ²½λ‘λ₯Ό λ°λΌ μ°μμ μ΄κ³ μ μ°ν μμ§μμ κ°λ₯νκ² ν©λλ€. μ΄λ₯Ό ν΅ν΄ μ€μ 물리 λ²μΉμ λͺ¨λ°©νκ±°λ μμ μ μΈ λμμΈμ λ°λ₯΄λ μ κ΅ν μ λλ©μ΄μ
μ λ§λ€ μ μμ΅λλ€.
ν΅μ¬ κ°λ κ³Ό μμ±
CSS Motion Pathλ₯Ό ν¨κ³Όμ μΌλ‘ νμ©νλ €λ©΄ ν΅μ¬ μμ±μ μ΄ν΄νλ κ²μ΄ μ€μν©λλ€:
offset-path
: μ΄ μμ±μ μμκ° μ΄λν κ²½λ‘λ₯Ό μ μν©λλ€. μ¬λ¬ κ°μ κ°μ§ μ μμ΅λλ€:url()
: HTML λ΄μ μ μλκ±°λ μΈλΆ SVG νμΌμ μλ SVG κ²½λ‘ μμλ₯Ό μ°Έμ‘°ν©λλ€.path()
: SVG κ²½λ‘ κ΅¬λ¬Έμ μ¬μ©νμ¬ CSS λ΄μμ μ§μ κ²½λ‘λ₯Ό μ μν μ μμ΅λλ€.ray()
: (μ€νμ κΈ°λ₯) μ§μ κ²½λ‘λ₯Ό μμ±ν©λλ€.none
: λͺ¨μ κ²½λ‘ μ λλ©μ΄μ μ λΉνμ±νν©λλ€.offset-distance
: μ΄ μμ±μoffset-path
λ₯Ό λ°λΌ μμμ μμΉλ₯Ό κ²°μ ν©λλ€. κ°μ λ²μλ0%
μμ100%
κΉμ§μ΄λ©°, κ°κ° κ²½λ‘μ μμκ³Ό λμ λνλ λλ€. λ°±λΆμ¨, κΈΈμ΄(px, em λ±) λλ κ³μ°λ κ°μ μ¬μ©ν μ μμ΅λλ€.offset-rotate
: μ΄ μμ±μ μμκ° κ²½λ‘λ₯Ό λ°λΌ μμ§μΌ λμ λ°©ν₯μ μ μ΄ν©λλ€. λ€μκ³Ό κ°μ κ°μ κ°μ§ μ μμ΅λλ€:auto
: μμκ° κ²½λ‘μ μ μ μ λ§μΆ° μλμΌλ‘ νμ ν©λλ€.auto
:auto
μ μ μ¬νμ§λ§ μΆκ°μ μΈ νμ κ°λλ₯Ό λν©λλ€.
: μμμ λν κ³ μ λ νμ κ°λλ₯Ό μ§μ ν©λλ€.motion-offset
: (λ¨μΆ μμ±)offset-path
μoffset-distance
λ₯Ό κ²°ν©ν λ¨μΆ μμ±μ λλ€.motion-rotation
: (λ¨μΆ μμ±)offset-rotate
λ₯Ό λ€λ₯Έ λ³ν μμ±κ³Ό κ²°ν©ν λ¨μΆ μμ±μ λλ€.
μ€μ©μ μΈ μμ
μμ 1: SVG κ²½λ‘λ₯Ό λ°λΌ μμ μ λλ©μ΄μ νκΈ°
μ΄ μμ λ 미리 μ μλ SVG κ²½λ‘λ₯Ό λ°λΌ HTML μμλ₯Ό μ΄λνλ λ°©λ²μ 보μ¬μ€λλ€.
HTML:
<svg width="500" height="200">
<path id="myPath" d="M50,100 C150,20 350,180 450,100" fill="none" stroke="black"/>
</svg>
<div id="myElement">Element</div>
CSS:
#myElement {
width: 50px;
height: 50px;
background-color: dodgerblue;
position: absolute; /* Required for motion path to work */
offset-path: url(#myPath);
animation: moveAlongPath 5s linear infinite;
}
@keyframes moveAlongPath {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
μ΄ μμ μμλ IDκ° "myPath"μΈ SVG κ²½λ‘κ° μ μλ©λλ€. "myElement" divμ offset-path
μμ±μ url(#myPath)
λ‘ μ€μ λμ΄ SVG κ²½λ‘μ μ°κ²°λ©λλ€. animation
μμ±μ "moveAlongPath"λΌλ μ΄λ¦μ μ λλ©μ΄μ
μ μ μ©νμ¬ 5μ΄ λμ offset-distance
λ₯Ό 0%μμ 100%λ‘ λ³κ²½νμ¬ μ°μμ μΈ μ λλ©μ΄μ
루νλ₯Ό λ§λλλ€.
μμ 2: path()
ν¨μ μ¬μ©νκΈ°
μ΄ μμ λ path()
ν¨μλ₯Ό μ¬μ©νμ¬ CSS λ΄μμ μ§μ κ²½λ‘λ₯Ό μ μνλ λ°©λ²μ 보μ¬μ€λλ€.
HTML:
<div id="myElement2">Element 2</div>
CSS:
#myElement2 {
width: 50px;
height: 50px;
background-color: orange;
position: absolute;
offset-path: path("M50,50 C150,20 350,180 450,50");
animation: moveAlongPath2 5s linear infinite;
}
@keyframes moveAlongPath2 {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
μ¬κΈ°μλ μ΄μ μμ μ λμΌν SVG κ²½λ‘ λ°μ΄ν°λ‘ path()
ν¨μλ₯Ό μ¬μ©νμ¬ offset-path
κ° μ§μ μ μλ©λλ€. λλ¨Έμ§ μ½λλ μ μ¬νκ² μ μ§λμ΄ λμΌν μ λλ©μ΄μ
ν¨κ³Όλ₯Ό λ
λλ€.
μμ 3: offset-rotate
λ‘ νμ μ μ΄νκΈ°
μ΄ μμ λ offset-rotate
μμ±μ μ¬μ©νμ¬ μμκ° κ²½λ‘λ₯Ό λ°λΌ μ΄λν λ λ°©ν₯μ μ μ΄νλ λ°©λ²μ 보μ¬μ€λλ€.
HTML:
<svg width="500" height="200">
<path id="myPath3" d="M50,100 C150,20 350,180 450,100" fill="none" stroke="black"/>
</svg>
<div id="myElement3">Element 3</div>
CSS:
#myElement3 {
width: 50px;
height: 50px;
background-color: lightgreen;
position: absolute;
offset-path: url(#myPath3);
offset-rotate: auto; /* Element rotates to align with the path */
animation: moveAlongPath3 5s linear infinite;
}
@keyframes moveAlongPath3 {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
offset-rotate: auto
λ‘ μ€μ νλ©΄ μμκ° κ° μ§μ μμ κ²½λ‘μ μ μ μ λ§μΆ° μλμΌλ‘ νμ νμ¬ λ μμ°μ€λ½κ³ λμ μΈ μ λλ©μ΄μ
μ λ§λλλ€.
μ¬μ© μ¬λ‘ λ° μμ©
CSS Motion Pathλ μΉ κ°λ°μμ λ€μκ³Ό κ°μ λ€μν μμ© νλ‘κ·Έλ¨μ μ 곡ν©λλ€:
- λ§€λ ₯μ μΈ λ‘λ© μ λλ©μ΄μ μ μ: λ¨μν μ€νΌλ λμ Motion Pathλ₯Ό μ¬μ©νμ¬ μ¬μ©μ μ§μ κ²½λ‘λ₯Ό λ°λΌ μμλ₯Ό μ λλ©μ΄μ ννμ¬ λ‘λ© μ§ν μν©μ μκ°μ μΌλ‘ λ λ§€λ ₯μ μΈ λ°©μμΌλ‘ νμν©λλ€. μλ₯Ό λ€μ΄, 곑μ κ²½λ‘λ₯Ό λ°λ₯΄λ μ§νλ₯ νμμ€μ΄λ λ‘λ© νμκΈ° μ£Όμλ₯Ό λλ μμ΄μ½ λ±μ΄ μμ΅λλ€.
- μ¬μ©μ μΈν°νμ΄μ€ μμ κ°ν: κ²½λ‘λ₯Ό λ°λΌ UI μμλ₯Ό μ λλ©μ΄μ ννμ¬ μ¬μ©μ μνΈμμ©μ λν νΌλλ°±μ μ 곡νκ±°λ μ¬μ©μλ₯Ό νλ‘μΈμ€ μ λ°μ κ±Έμ³ μλ΄ν©λλ€. μλ₯Ό λ€μ΄, 곑μ κ²½λ‘λ₯Ό λ°λΌ μ¬λΌμ΄λλλ μλ¦Όμ΄λ μν κ²½λ‘λ₯Ό λ°λΌ νμ₯λλ λ©λ΄ νλͺ© λ±μ΄ μμ΅λλ€.
- μΈν°λν°λΈ μΈν¬κ·Έλν½ μ μ: Motion Pathλ₯Ό μ¬μ©νμ¬ λ°μ΄ν° μκ°νλ₯Ό μ λλ©μ΄μ ννκ³ μμ§μμ ν΅ν΄ μ€ν 리λ₯Ό μ λ¬νλ μΈν°λν°λΈ μΈν¬κ·Έλν½μ λ§λλλ€. μλ₯Ό λ€μ΄, κ·Έλνμ μ μ μ λλ©μ΄μ ννμ¬ μκ° κ²½κ³Όμ λ°λ₯Έ μΆμΈλ₯Ό 보μ¬μ£Όκ±°λ μ§λμμ μμλ₯Ό μ΄λμμΌ μ§λ¦¬μ λ°μ΄ν°λ₯Ό μ€λͺ ν μ μμ΅λλ€.
- λͺ°μ ν μΉμ¬μ΄νΈ λ΄λΉκ²μ΄μ ꡬμΆ: Motion Pathλ₯Ό ꡬννμ¬ λ νΉνκ³ λ§€λ ₯μ μΈ λ΄λΉκ²μ΄μ κ²½νμ λ§λλλ€. μλ₯Ό λ€μ΄, λ©λ΄ νλͺ©μ 곑μ κ²½λ‘λ₯Ό λ°λΌ μ λλ©μ΄μ ννκ±°λ, λ€λ₯Έ κ²½λ‘λ₯Ό λ°λΌ λ€λ₯Έ μλλ‘ μμλ₯Ό μμ§μ¬ μμ°¨ ν¨κ³Ό(parallax effect)λ₯Ό λ§λ€ μ μμ΅λλ€.
- μΉ λμμΈμ μμ μ κ°κ° λνκΈ°: Motion Pathλ₯Ό νμ©νμ¬ μΉμ¬μ΄νΈμ μκ°μ λ§€λ ₯μ ν₯μμν€λ μμνκ² λ―Έμ μΈ μ λλ©μ΄μ μ λ§λλλ€. μλ₯Ό λ€μ΄, 볡μ‘ν κ²½λ‘λ₯Ό λ°λΌ μΆμμ μΈ λͺ¨μμ μ λλ©μ΄μ ννμ¬ λμ μΈ λ°°κ²½μ λ§λ€κ±°λ μΌλ¬μ€νΈλ μ΄μ μ λ―Έλ¬ν μμ§μμ μΆκ°ν μ μμ΅λλ€.
- κ²μ κ°λ°: 미리 μ μλκ±°λ λμ μΌλ‘ μμ±λ κ²½λ‘λ₯Ό λ°λΌ μΊλ¦ν°, λ°μ¬μ²΄ λλ κΈ°ν κ²μ μμλ₯Ό μ λλ©μ΄μ νν©λλ€. μ΄λ κ°λ¨ν νλ«νΌ κ²μμ μμ§μλΆν° 볡μ‘ν κ³΅μ€ κΈ°λμ μ΄λ₯΄κΈ°κΉμ§ λͺ¨λ κ²μ μ¬μ©λ μ μμ΅λλ€.
μ κ·Όμ± κ³ λ €μ¬ν
CSS Motion Pathλ μΉμ¬μ΄νΈμ μκ°μ λ§€λ ₯μ ν₯μμν¬ μ μμ§λ§, λͺ¨λ μ¬μ©μκ° μ½ν μΈ μ μ κ·Όνκ³ μ΄ν΄ν μ μλλ‘ μ κ·Όμ±μ κ³ λ €νλ κ²μ΄ μ€μν©λλ€. λ€μμ λͺ κ°μ§ μ£Όμ κ³ λ €μ¬νμ λλ€:
- λ체 μ½ν μΈ μ 곡: μ λλ©μ΄μ μ΄ μ€μν μ 보λ₯Ό μ λ¬νλ κ²½μ°, μ λλ©μ΄μ μ 보거λ μνΈμμ©ν μ μλ μ¬μ©μλ₯Ό μν΄ λ체 ν μ€νΈ μ€λͺ μ΄λ μ μ λ²μ μ μ½ν μΈ λ₯Ό μ 곡νμΈμ.
- μ λλ©μ΄μ μλ μ μ΄: λΉ λ₯΄κ±°λ 볡μ‘ν μ λλ©μ΄μ μ μΌλΆ μ¬μ©μμκ² μ°λ§νκ±°λ λ°©ν₯ κ°κ°μ μκ² ν μ μμΌλ―λ‘, μ¬μ©μκ° μ λλ©μ΄μ μλλ₯Ό μ μ΄νκ±°λ μμ ν μΌμ μ€μ§ν μ μλλ‘ νμ©νμΈμ. CSSλ μ΄μ μ¬μ©μ μ νΈλλ₯Ό κ°μ§νκΈ° μν΄ `prefers-reduced-motion` λ―Έλμ΄ μΏΌλ¦¬λ₯Ό μ 곡ν©λλ€.
- κΉλΉ‘μ΄λ μ λλ©μ΄μ νΌνκΈ°: κΉλΉ‘μ΄λ μ λλ©μ΄μ μ κ΄κ³Όλ―Όμ± κ°μ§μ΄ μλ μ¬μ©μμκ² λ°μμ μ λ°ν μ μμΌλ―λ‘ μ¬μ©μ νΌνμΈμ.
- μΆ©λΆν λλΉ λ³΄μ₯: μ λλ©μ΄μ μμμ λ°°κ²½ κ°μ λλΉκ° μκ° μ₯μ κ° μλ μ¬μ©μμκ² μΆ©λΆνμ§ νμΈνμΈμ.
- 보쑰 κΈ°μ λ‘ ν μ€νΈ: μ€ν¬λ¦° 리λμ κ°μ 보쑰 κΈ°μ λ‘ μΉμ¬μ΄νΈλ₯Ό ν μ€νΈνμ¬ μ λλ©μ΄μ μ΄ μ κ·Ό κ°λ₯νκ³ μ΄ν΄ν μ μλμ§ νμΈνμΈμ.
μ±λ₯ μ΅μ ν
μ λλ©μ΄μ μ μΉμ¬μ΄νΈ μ±λ₯μ μν₯μ μ€ μ μμΌλ―λ‘, λΆλλ½κ³ ν¨μ¨μ μΈ λ λλ§μ μν΄ CSS Motion Path μ λλ©μ΄μ μ μ΅μ ννλ κ²μ΄ μ€μν©λλ€. λ€μμ λͺ κ°μ§ νμ λλ€:
- νλμ¨μ΄ κ°μ μ¬μ©:
transform: translateZ(0)
λλbackface-visibility: hidden
κ³Ό κ°μ CSS μμ±μ νμ©νμ¬ νλμ¨μ΄ κ°μμ νΈλ¦¬κ±°νλ©΄ μ λλ©μ΄μ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€. - κ²½λ‘ λ¨μν: μ μ΄μ μ΄ μ μ λ κ°λ¨ν κ²½λ‘λ₯Ό μ¬μ©νμ¬ λ λλ§ μ€λ²ν€λλ₯Ό μ€μ΄μΈμ.
- SVG νμΌ μ΅μ ν: SVG κ²½λ‘λ₯Ό μ¬μ©νλ κ²½μ°, SVG νμΌμ μ΅μ ννμ¬ ν¬κΈ°μ 볡μ‘μ±μ μ€μ΄μΈμ.
- λ무 λ§μ μμλ₯Ό λμμ μ λλ©μ΄μ νμ§ μκΈ°: λ§μ μμ μμλ₯Ό λμμ μ λλ©μ΄μ νλ©΄ λΈλΌμ°μ μ 리μμ€λ₯Ό μλͺ¨ν μ μμ΅λλ€. μμλ₯Ό λ°°μΉλ‘ μ λλ©μ΄μ νκ±°λ μ€νλΌμ΄νΈ μνΈμ κ°μ κΈ°μ μ μ¬μ©νλ κ²μ κ³ λ €νμΈμ.
will-change
μμ± μ μ€νκ² μ¬μ©νκΈ°:will-change
μμ±μ λΈλΌμ°μ μ μμ λ λ³κ²½ μ¬νμ μλ € λ λλ§μ μ΅μ νν μ μλλ‘ ν©λλ€. κ·Έλ¬λ κ³Όλνκ² μ¬μ©νλ©΄ μ±λ₯μ λΆμ μ μΈ μν₯μ λ―ΈμΉ μ μμ΅λλ€. νλ°νκ² μ λλ©μ΄μ λλ μμμλ§ μ¬μ©νμΈμ.- μ λλ©μ΄μ νλ‘νμΌλ§: λΈλΌμ°μ κ°λ°μ λꡬλ₯Ό μ¬μ©νμ¬ μ λλ©μ΄μ μ νλ‘νμΌλ§νκ³ μ±λ₯ λ³λͺ© νμμ μλ³νμΈμ.
λΈλΌμ°μ νΈνμ±
CSS Motion Pathλ Chrome, Firefox, Safari, Edgeλ₯Ό ν¬ν¨ν μ΅μ λΈλΌμ°μ μμ μ μ§μλ©λλ€. κ·Έλ¬λ ꡬν λΈλΌμ°μ λ μ΄ κΈ°λ₯μ μ§μνμ§ μμ μ μμΌλ―λ‘ ν΄λΉ μ¬μ©μλ₯Ό μν΄ ν΄λ°±(fallback)μ΄λ λ체 μ루μ μ μ 곡νλ κ²μ΄ μ€μν©λλ€.
Modernizrμ κ°μ κΈ°λ₯ κ°μ§ κΈ°μ μ μ¬μ©νμ¬ λΈλΌμ°μ κ° CSS Motion Pathλ₯Ό μ§μνλμ§ νμΈνκ³ κ·Έμ λ°λΌ λ체 μ½ν μΈ λ κΈ°λ₯μ μ 곡ν μ μμ΅λλ€.
κ²°λ‘
CSS Motion Pathλ μΉμμ 볡μ‘νκ³ μκ°μ μΌλ‘ λ©μ§ μ λλ©μ΄μ μ λ§λ€κΈ° μν κ°λ ₯ν λꡬμ λλ€. ν΅μ¬ μμ±μ μ΄ν΄νκ³ , μ€μ©μ μΈ μμ λ₯Ό νꡬνλ©°, μ κ·Όμ±κ³Ό μ±λ₯μ κ³ λ €ν¨μΌλ‘μ¨ κ°λ°μλ Motion Pathμ λͺ¨λ μ μ¬λ ₯μ λ°ννκ³ λ§€λ ₯μ μ΄κ³ λμ μΈ μ¬μ©μ κ²½νμ λ§λ€ μ μμ΅λλ€. μΉ κΈ°μ μ΄ κ³μ λ°μ ν¨μ λ°λΌ CSS Motion Pathλ μΉ μ λλ©μ΄μ μ λ―Έλλ₯Ό νμ±νλ λ° μ μ λ μ€μν μν μ ν κ²μ λλ€.
λ‘λ© μ λλ©μ΄μ μ λ§λ€λ , UI μμλ₯Ό ν₯μμν€λ , λͺ°μ ν μΉμ¬μ΄νΈ λ΄λΉκ²μ΄μ μ λ§λ€λ , CSS Motion Pathλ μΉ λμμΈμ μλͺ μ λΆμ΄λ£λ λ€μ¬λ€λ₯νκ³ μ°½μμ μΈ λ°©λ²μ μ 곡ν©λλ€. λ€μν κ²½λ‘, νμ κΈ°μ , μ λλ©μ΄μ νμ΄λ°μ μ€ννμ¬ μ΄ ν₯λ―Έλ‘μ΄ κΈ°λ₯μ 무νν κ°λ₯μ±μ λ°κ²¬ν΄ 보μΈμ.
μΆκ° νμ΅ μλ£
- MDN μΉ λ¬Έμ: offset-path
- CSS-Tricks: offset-path
- GreenSock (GSAP): GSAPλ μλ°μ€ν¬λ¦½νΈ μ λλ©μ΄μ λΌμ΄λΈλ¬λ¦¬μ΄μ§λ§, κ°λ ₯ν Motion Path κΈ°λ₯μ μ 곡νλ©° λ κ³ κΈ μ μ΄κ° νμν νλ‘μ νΈμ μ μ©ν λμμ΄ λ μ μμ΅λλ€.